/*
 * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
 *
 * This Software is licensed under one of the following licenses:
 * 
 * 1) under the terms of the "Common Public License 1.0" a copy of which is
 *    in the file LICENSE.txt in the root directory. The license is also
 *    available from the Open Source Initiative, see 
 *    http://www.opensource.org/licenses/cpl.php.
 * 
 * 2) under the terms of the "The BSD License" a copy of which is in the file
 *    LICENSE2.txt in the root directory. The license is also available from
 *    the Open Source Initiative, see
 *    http://www.opensource.org/licenses/bsd-license.php.
 * 
 * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
 *    copy of which is in the file LICENSE3.txt in the root directory. The
 *    license is also available from the Open Source Initiative, see
 *    http://www.opensource.org/licenses/gpl-license.php.
 * 
 * Licensee has the right to choose one of the above licenses.
 * 
 * Redistributions of source code must retain the above copyright
 * notice and one of the license notices.
 * 
 * Redistributions in binary form must reproduce both the above copyright
 * notice, one of the license notices in the documentation
 * and/or other materials provided with the distribution.
 */

/****************************************************************
 *
 * HEADER: udat.h
 *
 * PURPOSE: defines the user DAT API
 *
 * Description: Header file for "uDAPL: User Direct Access Programming
 * Library, Version: 1.2"
 *
 * Mapping rules:
 *   All global symbols are prepended with DAT_ or dat_
 *   All DAT objects have an 'api' tag which, such as 'ep' or 'lmr'
 *   The method table is in the provider definition structure.
 *
 ***************************************************************/

#ifndef _UDAT_H_
#define _UDAT_H_

#include <dat/udat_config.h>

#include <dat/dat_platform_specific.h>

typedef enum dat_mem_type
{
        /* Shared between udat and kdat */
    DAT_MEM_TYPE_VIRTUAL              = 0x00,
    DAT_MEM_TYPE_LMR                  = 0x01,
        /* udat specific */
    DAT_MEM_TYPE_SHARED_VIRTUAL       = 0x02
} DAT_MEM_TYPE;

/* dat handle types */
typedef enum dat_handle_type
{
    DAT_HANDLE_TYPE_CR,
    DAT_HANDLE_TYPE_EP,
    DAT_HANDLE_TYPE_EVD,
    DAT_HANDLE_TYPE_IA,
    DAT_HANDLE_TYPE_LMR,
    DAT_HANDLE_TYPE_PSP,
    DAT_HANDLE_TYPE_PZ,
    DAT_HANDLE_TYPE_RMR,
    DAT_HANDLE_TYPE_RSP,
    DAT_HANDLE_TYPE_CNO,
    DAT_HANDLE_TYPE_SRQ
} DAT_HANDLE_TYPE;

/* EVD state consists of three orthogonal substates.  One for
 * enabled/disabled,one for waitable/unwaitable, and one for
 * configuration.  Within each substate the values are mutually
 * exclusive.
 */
typedef enum dat_evd_state
{
    DAT_EVD_STATE_ENABLED             = 0x01,
    DAT_EVD_STATE_DISABLED            = 0x02,
    DAT_EVD_STATE_WAITABLE            = 0x04,
    DAT_EVD_STATE_UNWAITABLE          = 0x08,
    DAT_EVD_STATE_CONFIG_NOTIFY       = 0x10,
    DAT_EVD_STATE_CONFIG_SOLICITED    = 0x20,
    DAT_EVD_STATE_CONFIG_THRESHOLD    = 0x30
} DAT_EVD_STATE;

typedef enum dat_evd_param_mask
{
    DAT_EVD_FIELD_IA_HANDLE           = 0x01,
    DAT_EVD_FIELD_EVD_QLEN            = 0x02,
    DAT_EVD_FIELD_EVD_STATE           = 0x04,
    DAT_EVD_FIELD_CNO                 = 0x08,
    DAT_EVD_FIELD_EVD_FLAGS           = 0x10,
    DAT_EVD_FIELD_ALL                 = 0x1F
} DAT_EVD_PARAM_MASK;

typedef DAT_UINT64 DAT_PROVIDER_ATTR_MASK;

#include <dat/dat.h>

typedef DAT_HANDLE      DAT_CNO_HANDLE;

struct dat_evd_param
{
    DAT_IA_HANDLE               ia_handle;
    DAT_COUNT                   evd_qlen;
    DAT_EVD_STATE               evd_state;
    DAT_CNO_HANDLE              cno_handle;
    DAT_EVD_FLAGS               evd_flags;
};

#define DAT_LMR_COOKIE_SIZE 40 /* size of DAT_LMR_COOKIE in bytes */
typedef char (* DAT_LMR_COOKIE)[DAT_LMR_COOKIE_SIZE];

/* Format for OS wait proxy agent function */

typedef void (*DAT_AGENT_FUNC)
(
    DAT_PVOID,                 /* instance data */
    DAT_EVD_HANDLE             /* Event Dispatcher*/
);

/* Definition */

typedef struct dat_os_wait_proxy_agent
{
    DAT_PVOID                   instance_data;
    DAT_AGENT_FUNC              proxy_agent_func;
} DAT_OS_WAIT_PROXY_AGENT;

/* Define NULL Proxy agent */

#define DAT_OS_WAIT_PROXY_AGENT_NULL \
    (DAT_OS_WAIT_PROXY_AGENT) {      \
    (DAT_PVOID) NULL,                \
    (DAT_AGENT_FUNC) NULL}

/* Flags */

/* The value specified by the uDAPL Consumer for dat_ia_open to indicate
 * that no async EVD should be created for the opening instance of an IA.
 * The same IA has been open before that has the only async EVD to
 * handle async errors for all open instances of the IA.
 */

#define DAT_EVD_ASYNC_EXISTS (DAT_EVD_HANDLE) 0x1

/*
 * The value returned by the dat_ia_query for the case when there is no
 * async EVD for the IA instance. The Consumer specified the value of
 * DAT_EVD_ASYNC_EXISTS for the async_evd_handle for dat_ia_open.
 */

#define DAT_EVD_OUT_OF_SCOPE (DAT_EVD_HANDLE) 0x2

/*
 * Memory types
 *
 * Specifying memory type for LMR create. A Consumer must use a single
 * value when registering memory. The union of any of these
 * flags is used in the Provider parameters to indicate what memory
 * type Provider supports for LMR memory creation.
 */



/* For udapl only */

typedef struct dat_shared_memory
{
    DAT_PVOID                   virtual_address;
    DAT_LMR_COOKIE              shared_memory_id;
} DAT_SHARED_MEMORY;

typedef union dat_region_description
{
    DAT_PVOID                   for_va;
    DAT_LMR_HANDLE              for_lmr_handle;
    DAT_SHARED_MEMORY           for_shared_memory;	/* For udapl only */
} DAT_REGION_DESCRIPTION;

/* LMR Arguments */

struct dat_lmr_param
{
    DAT_IA_HANDLE               ia_handle;
    DAT_MEM_TYPE                mem_type;
    DAT_REGION_DESCRIPTION      region_desc;
    DAT_VLEN                    length;
    DAT_PZ_HANDLE               pz_handle;
    DAT_MEM_PRIV_FLAGS          mem_priv;
    DAT_LMR_CONTEXT             lmr_context;
    DAT_RMR_CONTEXT             rmr_context;
    DAT_VLEN                    registered_size;
    DAT_VADDR                   registered_address;
};


typedef struct dat_cno_param
{
    DAT_IA_HANDLE               ia_handle;
    DAT_OS_WAIT_PROXY_AGENT     agent;
} DAT_CNO_PARAM;

typedef enum dat_cno_param_mask
{
    DAT_CNO_FIELD_IA_HANDLE          = 0x1,
    DAT_CNO_FIELD_AGENT              = 0x2,
    DAT_CNO_FIELD_ALL                = 0x3
} DAT_CNO_PARAM_MASK;


/* General Provider attributes. udat specific. */

typedef enum dat_pz_support
{
    DAT_PZ_UNIQUE,
    DAT_PZ_SHAREABLE
} DAT_PZ_SUPPORT;


#include <dat/udat_vendor_specific.h>

/* Provider should support merging of all event stream types. Provider
 * attribute specify support for merging different event stream types.
 * It is a 2D binary matrix where each row and column represents an event
 * stream type. Each binary entry is 1 if the event streams of its raw
 * and column can fed the same EVD, and 0 otherwise. The order of event
 * streams in row and column is the same as in the definition of
 * DAT_EVD_FLAGS: index 0 - Software Event, 1- Connection Request,
 * 2 - DTO Completion, 3 - Connection event, 4 - RMR Bind Completion,
 * 5 - Asynchronous event. By definition each diagonal entry is 1.
 * Consumer allocates an array for it and passes it IN as a pointer
 * for the array that Provider fills. Provider must fill the array
 * that Consumer passes.
 */

struct dat_provider_attr
{
    char                        provider_name[DAT_NAME_MAX_LENGTH];
    DAT_UINT32                  provider_version_major;
    DAT_UINT32                  provider_version_minor;
    DAT_UINT32                  dapl_version_major;
    DAT_UINT32                  dapl_version_minor;
    DAT_MEM_TYPE                lmr_mem_types_supported;
    DAT_IOV_OWNERSHIP           iov_ownership_on_return;
    DAT_QOS                     dat_qos_supported;
    DAT_COMPLETION_FLAGS        completion_flags_supported;
    DAT_BOOLEAN                 is_thread_safe;
    DAT_COUNT                   max_private_data_size;
    DAT_BOOLEAN                 supports_multipath;
    DAT_EP_CREATOR_FOR_PSP      ep_creator;
    DAT_PZ_SUPPORT              pz_support;
    DAT_UINT32                  optimal_buffer_alignment;
    const DAT_BOOLEAN           evd_stream_merging_supported[6][6];
    DAT_BOOLEAN                 srq_supported;
    DAT_COUNT                   srq_watermarks_supported;
    DAT_BOOLEAN                 srq_ep_pz_difference_supported;
    DAT_COUNT                   srq_info_supported;
    DAT_COUNT                   ep_recv_info_supported;
    DAT_BOOLEAN                 lmr_sync_req;
    DAT_BOOLEAN                 dto_async_return_guaranteed;
    DAT_BOOLEAN                 rdma_write_for_rdma_read_req;
    DAT_COUNT                   num_provider_specific_attr;
    DAT_NAMED_ATTR *            provider_specific_attr;
};

#define DAT_PROVIDER_FIELD_PROVIDER_NAME                 UINT64_C(0x0000001)
#define DAT_PROVIDER_FIELD_PROVIDER_VERSION_MAJOR        UINT64_C(0x0000002)
#define DAT_PROVIDER_FIELD_PROVIDER_VERSION_MINOR        UINT64_C(0x0000004)
#define DAT_PROVIDER_FIELD_DAPL_VERSION_MAJOR            UINT64_C(0x0000008)
#define DAT_PROVIDER_FIELD_DAPL_VERSION_MINOR            UINT64_C(0x0000010)
#define DAT_PROVIDER_FIELD_LMR_MEM_TYPE_SUPPORTED        UINT64_C(0x0000020)
#define DAT_PROVIDER_FIELD_IOV_OWNERSHIP                 UINT64_C(0x0000040)
#define DAT_PROVIDER_FIELD_DAT_QOS_SUPPORTED             UINT64_C(0x0000080)
#define DAT_PROVIDER_FIELD_COMPLETION_FLAGS_SUPPORTED    UINT64_C(0x0000100)
#define DAT_PROVIDER_FIELD_IS_THREAD_SAFE                UINT64_C(0x0000200)
#define DAT_PROVIDER_FIELD_MAX_PRIVATE_DATA_SIZE         UINT64_C(0x0000400)
#define DAT_PROVIDER_FIELD_SUPPORTS_MULTIPATH            UINT64_C(0x0000800)
#define DAT_PROVIDER_FIELD_EP_CREATOR                    UINT64_C(0x0001000)
#define DAT_PROVIDER_FIELD_PZ_SUPPORT                    UINT64_C(0x0002000)
#define DAT_PROVIDER_FIELD_OPTIMAL_BUFFER_ALIGNMENT      UINT64_C(0x0004000)
#define DAT_PROVIDER_FIELD_EVD_STREAM_MERGING_SUPPORTED  UINT64_C(0x0008000)
#define DAT_PROVIDER_FIELD_SRQ_SUPPORTED                 UINT64_C(0x0010000)
#define DAT_PROVIDER_FIELD_SRQ_WATERMARKS_SUPPORTED      UINT64_C(0x0020000)
#define DAT_PROVIDER_FIELD_SRQ_EP_PZ_DIFFERENCE_SUPPORTED UINT64_C(0x0040000)
#define DAT_PROVIDER_FIELD_SRQ_INFO_SUPPORTED            UINT64_C(0x0080000)
#define DAT_PROVIDER_FIELD_EP_RECV_INFO_SUPPORTED        UINT64_C(0x0100000)
#define DAT_PROVIDER_FIELD_LMR_SYNC_REQ                  UINT64_C(0x0200000)
#define DAT_PROVIDER_FIELD_DTO_ASYNC_RETURN_GUARANTEED   UINT64_C(0x0400000)
#define DAT_PROVIDER_FIELD_RDMA_WRITE_FOR_RDMA_READ_REQ  UINT64_C(0x0800000)
#define DAT_PROVIDER_FIELD_NUM_PROVIDER_SPECIFIC_ATTR    UINT64_C(0x1000000)
#define DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR        UINT64_C(0x2000000)

#define DAT_PROVIDER_FIELD_ALL                           UINT64_C(0x3FFFFFF)
#define DAT_PROVIDER_FIELD_NONE				 UINT64_C(0x0)

/**************************************************************/

/*
 * User DAT function call definitions,
 */


extern DAT_RETURN dat_lmr_create (
	IN      DAT_IA_HANDLE,		/* ia_handle            */
	IN      DAT_MEM_TYPE,		/* mem_type             */
	IN      DAT_REGION_DESCRIPTION, /* region_description   */
	IN      DAT_VLEN,		/* length               */
	IN      DAT_PZ_HANDLE,		/* pz_handle            */
	IN      DAT_MEM_PRIV_FLAGS,	/* privileges           */
	OUT     DAT_LMR_HANDLE *,	/* lmr_handle           */
	OUT     DAT_LMR_CONTEXT *,	/* lmr_context          */
	OUT     DAT_RMR_CONTEXT *,	/* rmr_context          */
	OUT     DAT_VLEN *,		/* registered_length    */
	OUT     DAT_VADDR * );		/* registered_address   */

/* Event Functions */

extern DAT_RETURN dat_evd_create (
	IN      DAT_IA_HANDLE,		/* ia_handle            */
	IN      DAT_COUNT,		/* evd_min_qlen         */
	IN      DAT_CNO_HANDLE,		/* cno_handle           */
	IN      DAT_EVD_FLAGS,		/* evd_flags            */
	OUT     DAT_EVD_HANDLE * );	/* evd_handle           */

extern DAT_RETURN dat_evd_modify_cno (
	IN      DAT_EVD_HANDLE,		/* evd_handle           */
	IN      DAT_CNO_HANDLE);	/* cno_handle           */

extern DAT_RETURN dat_cno_create (
	IN 	DAT_IA_HANDLE,		/* ia_handle            */
	IN 	DAT_OS_WAIT_PROXY_AGENT,/* agent                */
	OUT 	DAT_CNO_HANDLE *);	/* cno_handle           */

extern DAT_RETURN dat_cno_modify_agent (
	IN 	DAT_CNO_HANDLE,		 /* cno_handle           */
	IN 	DAT_OS_WAIT_PROXY_AGENT);/* agent                */

extern DAT_RETURN dat_cno_query (
	IN      DAT_CNO_HANDLE,		/* cno_handle            */
	IN      DAT_CNO_PARAM_MASK,	/* cno_param_mask        */
	OUT     DAT_CNO_PARAM * );	/* cno_param             */

extern DAT_RETURN dat_cno_free (
	IN DAT_CNO_HANDLE);		/* cno_handle            */

extern DAT_RETURN dat_cno_wait (
	IN  	DAT_CNO_HANDLE,		/* cno_handle            */
	IN  	DAT_TIMEOUT,		/* timeout               */
	OUT 	DAT_EVD_HANDLE *);	/* evd_handle            */

extern DAT_RETURN dat_evd_enable (
	IN      DAT_EVD_HANDLE);	/* evd_handle            */

extern DAT_RETURN dat_evd_wait (
	IN  	DAT_EVD_HANDLE,		/* evd_handle            */
	IN  	DAT_TIMEOUT,		/* Timeout               */
	IN  	DAT_COUNT,		/* Threshold             */
	OUT 	DAT_EVENT *,		/* event                 */
	OUT 	DAT_COUNT * );		/* n_more_events         */

extern DAT_RETURN dat_evd_disable (
	IN      DAT_EVD_HANDLE);	/* evd_handle            */

extern DAT_RETURN dat_evd_set_unwaitable (
	IN DAT_EVD_HANDLE);		/* evd_handle            */

extern DAT_RETURN dat_evd_clear_unwaitable (
	IN DAT_EVD_HANDLE);		/* evd_handle            */

#endif /* _UDAT_H_ */
